package com.atguigu.tingshu.album.service.impl;

import com.atguigu.tingshu.album.mapper.AlbumAttributeValueMapper;
import com.atguigu.tingshu.album.mapper.AlbumInfoMapper;
import com.atguigu.tingshu.album.mapper.AlbumStatMapper;
import com.atguigu.tingshu.album.service.AlbumInfoService;
import com.atguigu.tingshu.common.cache.GuiguCache;
import com.atguigu.tingshu.common.constant.SystemConstant;
import com.atguigu.tingshu.common.execption.GuiguException;
import com.atguigu.tingshu.common.util.AuthContextHolder;
import com.atguigu.tingshu.constant.RabbitConstant;
import com.atguigu.tingshu.model.album.AlbumAttributeValue;
import com.atguigu.tingshu.model.album.AlbumInfo;
import com.atguigu.tingshu.model.album.AlbumStat;
import com.atguigu.tingshu.query.album.AlbumInfoQuery;
import com.atguigu.tingshu.vo.album.AlbumAttributeValueVo;
import com.atguigu.tingshu.vo.album.AlbumInfoVo;
import com.atguigu.tingshu.vo.album.AlbumListVo;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.redisson.api.RBloomFilter;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 专辑信息的实现类
 */
@Slf4j
@Service
@SuppressWarnings({"unchecked", "rawtypes"})
@Transactional(rollbackFor = Exception.class)
public class AlbumInfoServiceImpl extends ServiceImpl<AlbumInfoMapper, AlbumInfo> implements AlbumInfoService {

    @Autowired
    private AlbumInfoMapper albumInfoMapper;

    @Autowired
    private AlbumAttributeValueMapper albumAttributeValueMapper;

    @Autowired
    private AlbumStatMapper albumStatMapper;

    @Resource
    private RabbitTemplate rabbitTemplate;

    @Autowired
    private RBloomFilter rBloomFilter;

    /**
     * 新增专辑
     *
     * @param albumInfoVo
     */
    @Override
    public void saveAlbumInfo(AlbumInfoVo albumInfoVo) {
        //保存专辑信息
        //将VO转为DO
        AlbumInfo albumInfo = new AlbumInfo();
        BeanUtils.copyProperties(albumInfoVo, albumInfo);
        //补全属性
        Long userId = AuthContextHolder.getUserId();
        albumInfo.setUserId(userId);
        albumInfo.setStatus(SystemConstant.ALBUM_STATUS_PASS);
        //保存
        int i = albumInfoMapper.insert(albumInfo);
        if (i <= 0) {
            throw new GuiguException(201, "新增专辑失败");
        }
        //获取专辑的id
        Long albumId = albumInfo.getId();
        rBloomFilter.add(albumId);

        //保存专辑的标签信息
        saveAlbumAttribute(albumId, albumInfoVo.getAlbumAttributeValueVoList());

        //初始化专辑的统计数据
        saveAlbumStat(albumId);

        //给rabbitmq发消息,将专辑信息更新到es中
        if ("1".equals(albumInfoVo.getIsOpen())){
            //将专辑添加到es中
            rabbitTemplate.convertAndSend(
                    RabbitConstant.ELASTICSEARCH_EXCHANGE,
                    RabbitConstant.ELASTICSEARCH_ADD_ROUTING,
                    albumId + "");
            //将数据同步到布隆过滤器中
            rBloomFilter.add(albumInfo.getId());
        }

    }

    /**
     * 获取当前用户专辑列表
     *
     * @return
     */
    @Override
    public List<AlbumInfo> findUserAlbumList() {
        //获取用户id
        Long userId = AuthContextHolder.getUserId();
        return albumInfoMapper.selectPage(new Page<AlbumInfo>(1, 10),
                new LambdaQueryWrapper<AlbumInfo>().eq(AlbumInfo::getUserId, userId)
                        .orderBy(true, false, AlbumInfo::getId)).getRecords();
    }

    /**
     * 删除专辑
     *
     * @param albumId
     * @return
     */
    @Override
    public void removeAlbumInfo(Long albumId) {
        //获取用户id
        Long userId = AuthContextHolder.getUserId();
        //删除专辑信息
        int i = albumInfoMapper.delete(
                new LambdaQueryWrapper<AlbumInfo>().eq(AlbumInfo::getUserId, userId).eq(AlbumInfo::getId, albumId));
        if (i <= 0) {
            throw new GuiguException(201, "删除专辑信息失败");
        }

        //删除专辑标签
        i = albumAttributeValueMapper.delete(
                new LambdaQueryWrapper<AlbumAttributeValue>().eq(AlbumAttributeValue::getAlbumId, albumId));
        if (i < 0) {
            throw new GuiguException(201, "删除专辑标签失败");
        }

        //删除统计信息
        i = albumStatMapper.delete(new LambdaQueryWrapper<AlbumStat>().eq(AlbumStat::getAlbumId, albumId));
        if (i < 0) {
            throw new GuiguException(201, "删除统计信息失败");
        }
        //给rabbitmq发消息,将专辑信息从es/redis中删除
        rabbitTemplate.convertAndSend(
                RabbitConstant.ELASTICSEARCH_EXCHANGE,
                RabbitConstant.ELASTICSEARCH_REMOVE_ROUTING,
                albumId + "");
    }

    /**
     * 根据id更新专辑
     *
     * @param albumId
     * @param albumInfoVo
     */
    @Override
    public void updateAlbumInfoByAlbumId(Long albumId, AlbumInfoVo albumInfoVo) {
        //获取用户id
        Long userId = AuthContextHolder.getUserId();

        //更新专辑
        AlbumInfo albumInfo = new AlbumInfo();
        BeanUtils.copyProperties(albumInfoVo, albumInfo);
        albumInfo.setId(albumId);
        int i = albumInfoMapper.update(
                albumInfo, new LambdaQueryWrapper<AlbumInfo>().eq(AlbumInfo::getUserId, userId).eq(AlbumInfo::getId, albumId));
        if (i <= 0) {
            throw new GuiguException(201, "更新专辑失败");
        }

        //删除标签信息
        if (albumAttributeValueMapper.delete(
                new LambdaQueryWrapper<AlbumAttributeValue>().eq(AlbumAttributeValue::getAlbumId, albumId)) < 0) {
            throw new GuiguException(201, "更新专辑失败");
        }
        //保存标签
        List<AlbumAttributeValueVo> albumAttributeValueVoList = albumInfoVo.getAlbumAttributeValueVoList();
        if (albumAttributeValueVoList != null) {
            saveAlbumAttribute(albumInfo.getId(), albumAttributeValueVoList);
        }

        if ("1".equals(albumInfoVo.getIsOpen())){
            //将专辑添加到es中
            rabbitTemplate.convertAndSend(
                    RabbitConstant.ELASTICSEARCH_EXCHANGE,
                    RabbitConstant.ELASTICSEARCH_ADD_ROUTING,
                    albumId + "");
            //将数据同步到布隆过滤器中
            rBloomFilter.add(albumInfo.getId());
        }else {
            //将专辑从es中删除
            rabbitTemplate.convertAndSend(
                    RabbitConstant.ELASTICSEARCH_EXCHANGE,
                    RabbitConstant.ELASTICSEARCH_REMOVE_ROUTING,
                    albumId + "");
        }

    }

    /**
     * 专辑修改数据回显
     *
     * @param albumId
     * @return
     */
    @Override
    public AlbumInfo getAlbumInfo(Long albumId) {
        //获取用户id
        Long userId = AuthContextHolder.getUserId();
        //查询专辑数据
        AlbumInfo albumInfo = albumInfoMapper.selectOne(
                new LambdaQueryWrapper<AlbumInfo>().eq(AlbumInfo::getUserId, userId).eq(AlbumInfo::getId, albumId));
        if (albumInfo == null) {
            throw new GuiguException(201, "专辑不存在");
        }


        //根据专辑id查询属性集合
        List<AlbumAttributeValue> albumAttributeValueList =
                albumAttributeValueMapper.selectList(
                        new LambdaQueryWrapper<AlbumAttributeValue>().eq(AlbumAttributeValue::getAlbumId, albumId));

        //设置vo的属性集合
        albumInfo.setAlbumAttributeValueVoList(albumAttributeValueList);

        return albumInfo;
    }

    /**
     * 分页查询专辑
     *
     * @param page           分页信息
     * @param albumInfoQuery 查询条件
     * @return
     */
    @Override
    public IPage<AlbumListVo> findUserAlbumPage(IPage<AlbumListVo> page, AlbumInfoQuery albumInfoQuery) {
        //获取用户id
        Long userId = AuthContextHolder.getUserId();
        albumInfoQuery.setUserId(userId);
        return albumInfoMapper.findUserAlbumPage(page, albumInfoQuery);
    }

    /**
     * 初始化专辑的统计数据
     *
     * @param albumId
     */
    private void saveAlbumStat(Long albumId) {
        //创建DO
        AlbumStat albumStat = new AlbumStat();
        //设置专辑id
        albumStat.setAlbumId(albumId);

        //初始化播放量
        albumStat.setStatType(SystemConstant.ALBUM_STAT_PLAY);
        if (albumStatMapper.insert(albumStat) <= 0) {
            throw new GuiguException(201, "初始化播放量失败");
        }

        //初始化订阅量
        albumStat.setId(null);
        albumStat.setStatType(SystemConstant.ALBUM_STAT_SUBSCRIBE);
        if (albumStatMapper.insert(albumStat) <= 0) {
            throw new GuiguException(201, "初始化订阅量失败");
        }

        //初始化购买量
        albumStat.setId(null);
        albumStat.setStatType(SystemConstant.ALBUM_STAT_BROWSE);
        if (albumStatMapper.insert(albumStat) <= 0) {
            throw new GuiguException(201, "初始化购买量失败");
        }

        //初始化评论数
        albumStat.setId(null);
        albumStat.setStatType(SystemConstant.ALBUM_STAT_COMMENT);
        if (albumStatMapper.insert(albumStat) <= 0) {
            throw new GuiguException(201, "初始化评论数失败");
        }


    }

    /**
     * 保存专辑的标签信息
     *
     * @param albumId
     * @param albumAttributeValueVoList
     */
    private void saveAlbumAttribute(Long albumId, List<AlbumAttributeValueVo> albumAttributeValueVoList) {
        albumAttributeValueVoList.stream().forEach(albumAttributeValueVo -> {
            //将VO转换为DO
            AlbumAttributeValue albumAttributeValue = new AlbumAttributeValue();
            BeanUtils.copyProperties(albumAttributeValueVo, albumAttributeValue);
            albumAttributeValue.setAlbumId(albumId);
            if (albumAttributeValueMapper.insert(albumAttributeValue) <= 0) {
                throw new GuiguException(201, "新增标签信息失败");
            }
        });
    }

    /**
     * 根据专辑id获取专辑的统计信息
     *
     * @param albumId
     * @return
     */
    @GuiguCache(prefix = "getAlbumStat:")
    @Override
    public Map<String, Integer> getAlbumStat(Long albumId) {
        //获取统计信息
        List<AlbumStat> albumStatList = albumStatMapper.selectList(
                new LambdaQueryWrapper<AlbumStat>().eq(AlbumStat::getAlbumId, albumId));
        //将统计信息转换为map
        Map<String, Integer> map = albumStatList.stream().collect(
                Collectors.toMap(albumStat -> albumStat.getStatType(), albumStat -> albumStat.getStatNum()));
        return map;
    }

    /**
     * 根据专辑id获取属性值
     *
     * @param albumId
     * @return
     */
    @Override
    public List<AlbumAttributeValue> getAlbumAttributeValue(Long albumId) {
        return albumAttributeValueMapper.selectList(
                new LambdaQueryWrapper<AlbumAttributeValue>().eq(AlbumAttributeValue::getAlbumId,albumId));
    }

    /**
     * 根据专辑id获取专辑详情
     *
     * @param albumId
     * @return
     */
    @GuiguCache(prefix = "getAlbumInfo:")
    @Override
    public AlbumInfo getAlbumInfoById(Long albumId) {
        return baseMapper.selectById(albumId);
    }
}
